package com.filesys.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.filesys.core.IAction;
import com.filesys.core.util.FileSys;
import com.filesys.core.util.Transcoder;
import com.server.kit.FileKit;
import com.server.kit.StrKit;

public class ListAction implements IAction {

    private static final String[]                LEVEL       = new String[] { "B", "KB", "MB", "GB", "TB" };
    private static ThreadLocal<SimpleDateFormat> local       = new ThreadLocal<SimpleDateFormat>();
    private static final int                     BUFFER_SIZE = 1024 * 1024;

    @Override
    public void doAction(HttpServletRequest req, HttpServletResponse resp) {
        String path = req.getParameter("path");
        path = Transcoder.decode(path);
        path.toLowerCase().replace("null", "");
        File file = FileKit.getFile(path);
        try {
            if (file != null) {
                if (file.isDirectory()) {
                    File[] files = FileSys.getFiles(file);
                    renderFiles(resp, file, files);
                } else {
                    loadFile(resp, file);
                }
            } else {
                File[] files = FileSys.getRootFiles();
                renderFiles(resp, null, files);
            }
        } catch (Exception e) {}
    }

    private void loadFile(HttpServletResponse resp, File file) throws IOException {
        resp.setContentType(getContentType(file.getName()));
        resp.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8").replace("+", "%20"));
        //      resp.addHeader("Content-Disposition","attachment;filename=" + file.getName());
        resp.addHeader("Content-Length", String.valueOf(file.length()));
        OutputStream os = resp.getOutputStream();
        FileInputStream fis = null;
        try {
            fis = FileSys.getInputStream(file);
            byte[] bytes = new byte[BUFFER_SIZE];
            while (fis.read(bytes) != -1) {
                os.write(bytes);
            }
            os.flush();
        } catch (Exception e) {} finally {
            if (fis != null) {
                fis.close();
            }
        }
    }

    private void renderFiles(HttpServletResponse resp, File parentFile, File[] files) throws IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter pw = resp.getWriter();
        pw.println("<html>");
        pw.println("<head>");
        pw.println("<title>File System</title>");
        pw.println("<base href='/file'>");
        pw.println("</head>");
        pw.println("<body>");
        pw.println("<h1>File System</h1>");
        pw.println("<p style='border-bottom:1px solid black;'></p>");
        if (parentFile != null) {
            String parentPath = parentFile.getParent();
            parentPath = Transcoder.encode(parentPath);
            pw.println("<div style='margin-top:8px;margin-left:10px;margin-bottom:30px;'><a href='?path=" + parentPath + "' style='font-size:20px;'>返回上一级</a></div>");
        }
        pw.println("<div style='margin-top:8px;margin:0 40px;border-bottom: 1px solid #ccc;'>");
        pw.println("<div style='font-size:18px;float:left;'>文件</div>");
        pw.println("<div style='font-size:18px;float:right;width:200px;text-align:right;'>大小</div>");
        pw.println("<div style='font-size:18px;float:right;width:120px;text-align:right;'>时间</div>");
        pw.println("<div style='clear:both;'></div></div> ");
        if (files != null && files.length > 0) {
            for (File file : files) {
                String name = file.getName();
                name = StrKit.isBlank(name) ? file.getPath() : name;
                long size = file.isFile() ? file.length() : -1;
                if (size == 0 && file.isAbsolute()) {
                    continue;
                }
                long time = file.lastModified();
                String imgSrc = "imgs/res.png";
                if (file.isDirectory()) {
                    imgSrc = "imgs/folder.gif";
                }
                String path = Transcoder.encode(file.getPath());
                pw.println("<div style='margin-top:8px;margin:0 40px;'>");
                pw.println("<div style='float:left;'><img src='" + imgSrc + "' style='width:18px;margin-bottom: -3px;'/><a href='?path=" + path + "' style='font-size:18px;'>" + name + "</a></div>");
                pw.println("<div style='font-size:18px;float:right;width:200px;text-align:right;'>" + getFormatSize(size) + "</div>");
                pw.println("<div style='font-size:18px;float:right;width:200px;text-align:right;'>" + getFormatDate(time) + "</div>");
                pw.println("<div style='clear:both;'></div></div> ");
            }
        }
        pw.println("</body>");
        pw.println("</html>");
    }

    private String getFormatDate(long time) {
        SimpleDateFormat f = local.get();
        if (f == null) {
            f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            local.set(f);
        }
        return f.format(new Date(time));
    }

    private String getFormatSize(long size) {
        if (size == -1) {
            return "&nbsp;";
        } else {
            Double fs = size * 1.0;
            int level = 0;
            while ((fs / 1024) > 1) {
                level++;
                fs /= 1024;
            }
            return String.format("%.2f", fs) + LEVEL[level];
        }
    }

    private String getContentType(String filename) {
        String ContentType;
        switch (filename.substring(filename.lastIndexOf(".")).trim().toLowerCase()) {
            case ".asf":
                ContentType = "video/x-ms-asf";
                break;
            case ".avi":
                ContentType = "video/avi";
                break;
            case ".doc":
                ContentType = "application/msword";
                break;
            case ".zip":
                ContentType = "application/zip";
                break;
            case ".xls":
                ContentType = "application/vnd.ms-excel";
                break;
            case ".gif":
                ContentType = "image/gif";
                break;
            case ".jpg":
                ContentType = "image/jpeg";
                break;
            case "jpeg":
                ContentType = "image/jpeg";
                break;
            case ".wav":
                ContentType = "audio/wav";
                break;
            case ".mp3":
                ContentType = "audio/mpeg3";
                break;
            case ".mpg":
                ContentType = "video/mpeg";
                break;
            case ".mepg":
                ContentType = "video/mpeg";
                break;
            case ".rtf":
                ContentType = "application/rtf";
                break;
            case ".html":
                ContentType = "text/html";
                break;
            case ".htm":
                ContentType = "text/html";
                break;
            case ".txt":
                ContentType = "text/plain";
                break;
            default:
                ContentType = "application/octet-stream";
                break;
        }
        return ContentType;
    }
}
